package org.example.study11.deadlyembrace;

import java.util.concurrent.TimeUnit;

public class LockOrderingSolution {
    // 定义两个锁对象
    private static final Object lock1 = new Object();
    private static final Object lock2 = new Object();

    // 为锁分配固定的顺序：总是先获取编号小的锁
    // 这里假设lock1的"编号"小于lock2
    public static void main(String[] args) {
        Thread t1 = new Thread(() -> {
            // 按照固定顺序获取锁：先lock1，后lock2
            acquireLocksInOrder(lock1, lock2, "t1");
        });

        Thread t2 = new Thread(() -> {
            // 同样按照固定顺序获取锁：先lock1，后lock2
            acquireLocksInOrder(lock1, lock2, "t2");
        });

        t1.start();
        t2.start();
    }

    /**
     * 按照固定顺序获取两个锁
     * @param firstLock 第一个要获取的锁
     * @param secondLock 第二个要获取的锁
     * @param threadName 线程名称，用于日志输出
     */
    private static void acquireLocksInOrder(Object firstLock, Object secondLock, String threadName) {
        System.out.println(threadName + ": 开始按顺序获取锁");

        // 先获取第一个锁
        synchronized (firstLock) {
            System.out.println(threadName + ": 获取第一个锁成功");

            try {
                // 模拟业务处理
                TimeUnit.MILLISECONDS.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            // 再获取第二个锁
            synchronized (secondLock) {
                System.out.println(threadName + ": 获取第二个锁成功，执行关键业务");

                // 执行需要两个锁的业务逻辑
                performCriticalSection(threadName);
            }
        }
    }

    private static void performCriticalSection(String threadName) {
        System.out.println(threadName + ": 正在执行关键业务代码");
        try {
            TimeUnit.MILLISECONDS.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(threadName + ": 关键业务执行完成");
    }
}
